﻿//***************************************************************
// 类名：资源加载监视器
// 责任人：钟汶洁
// 修改日期：2015.7
// 功能：监视资源包加载过程，并在加载完毕后取出需要的资源
//***************************************************************

using UnityEngine;
using System.Collections;

/// <summary>
/// 加载监视器基类
/// </summary>

public abstract class AssetBundleLoadOperation : IEnumerator
{
	public object Current
	{
		get
		{
			return null;
		}
	}

	public bool MoveNext()
	{
		return !IsDone();
	}
	public void Reset()
	{

	}
	
    /// <summary>
    /// 帧更新
    /// </summary>
    /// <returns>true：工作中，false：工作完毕</returns>
	abstract public bool Update();
    /// <summary>
    /// 是否加载完毕
    /// </summary>
    /// <returns></returns>
	abstract public bool IsDone();
}

/// <summary>
/// 在编辑器中模拟加载场景的监视器
/// </summary>
public class AssetBundleLoadLevelSimulationOperation : AssetBundleLoadOperation
{	
	public AssetBundleLoadLevelSimulationOperation()
	{
	}
    /// <summary>
    /// 帧更新
    /// </summary>
    /// <returns>true：工作中，false：工作完毕</returns>
	public override bool Update()
	{
		return false;
	}
    /// <summary>
    /// 是否加载完毕
    /// </summary>
    /// <returns></returns>
	public override bool IsDone()
	{		
		return true;
	}
}

/// <summary>
/// 加载场景的监视器
/// </summary>
public class AssetBundleLoadLevelOperation : AssetBundleLoadOperation
{
    protected string m_AssetBundleName; // 资源包名
	protected string m_LevelName; // 场景名
	protected bool m_IsAdditive; // 是否在当前场景基础上增量加载
	protected string m_DownloadingError; // 加载过程中产生的异常信息
	protected AsyncOperation m_Request; // 异步加载请求

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="assetbundleName">资源包名</param>
    /// <param name="levelName">场景名</param>
    /// <param name="isAdditive">是否在当前场景基础上增量加载</param>
	public AssetBundleLoadLevelOperation(string assetbundleName, string levelName, bool isAdditive)
	{
		m_AssetBundleName = assetbundleName;
		m_LevelName = levelName;
		m_IsAdditive = isAdditive;
	}
    /// <summary>
    /// 帧更新
    /// </summary>
    /// <returns>true：工作中，false：工作完毕</returns>
	public override bool Update()
	{
        if (m_Request != null)
        {
            return false;
        }

        LoadedAssetBundle bundle = AssetBundleManager.Instance().GetLoadedAssetBundle(m_AssetBundleName, out m_DownloadingError);
        if (bundle != null)
        {
            if (m_IsAdditive)
            {
                //m_Request = Application.LoadLevelAdditiveAsync(m_LevelName);

                m_Request = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(m_LevelName,UnityEngine.SceneManagement.LoadSceneMode.Additive);
            }
            else
            {
                //m_Request = Application.LoadLevelAsync(m_LevelName);

                m_Request = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(m_LevelName,UnityEngine.SceneManagement.LoadSceneMode.Single);
            }
            return false;
        }
        else
        {
            return true;
        }
	}
    /// <summary>
    /// 是否加载完毕
    /// </summary>
    /// <returns></returns>
	public override bool IsDone()
	{
		// 加载过程中出现错误（有可能是在加载自身，也有可能是在加载依赖的资源）
		if (m_Request == null && m_DownloadingError != null)
		{
			Debug.LogError(m_DownloadingError);
			return true;
		}
		
		return m_Request != null && m_Request.isDone;
	}
}

/// <summary>
/// 加载资源的监视器基类
/// </summary>
public abstract class AssetBundleLoadAssetOperation : AssetBundleLoadOperation
{
    /// <summary>
    /// 从资源包中获取到指定类型的资源
    /// </summary>
    /// <typeparam name="T">资源类型</typeparam>
    /// <returns>资源对象</returns>
	public abstract T GetAsset<T>() where T : UnityEngine.Object;
}

/// <summary>
/// 在编辑器中模拟加载资源的监视器
/// </summary>
public class AssetBundleLoadAssetOperationSimulation : AssetBundleLoadAssetOperation
{
	Object m_SimulatedObject; // 资源对象
	
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="simulatedObject">资源对象</param>
	public AssetBundleLoadAssetOperationSimulation(Object simulatedObject)
	{
		m_SimulatedObject = simulatedObject;
	}

    /// <summary>
    /// 从资源包中获取到指定类型的资源
    /// </summary>
    /// <typeparam name="T">资源类型</typeparam>
    /// <returns>资源对象</returns>
	public override T GetAsset<T>()
	{
		return m_SimulatedObject as T;
	}
    /// <summary>
    /// 帧更新
    /// </summary>
    /// <returns>true：工作中，false：工作完毕</returns>
	public override bool Update()
	{
		return false;
	}
    /// <summary>
    /// 是否加载完毕
    /// </summary>
    /// <returns></returns>
	public override bool IsDone()
	{
		return true;
	}
}

/// <summary>
/// 加载资源的监视器
/// </summary>
public class AssetBundleLoadAssetOperationFull : AssetBundleLoadAssetOperation
{
	protected string m_AssetBundleName; // 资源包名
	protected string m_AssetName; // 资源名
	protected string m_DownloadingError; // 加载过程中产生的异常信息
	protected System.Type m_Type; // 资源类型
	protected AssetBundleRequest m_Request = null; // 异步加载请求

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="bundleName">资源包名</param>
    /// <param name="assetName">资源名</param>
    /// <param name="type">资源类型</param>
	public AssetBundleLoadAssetOperationFull(string bundleName, string assetName, System.Type type)
	{
		m_AssetBundleName = bundleName;
		m_AssetName = assetName;
		m_Type = type;
	}
    /// <summary>
    /// 从资源包中获取到指定类型的资源
    /// </summary>
    /// <typeparam name="T">资源类型</typeparam>
    /// <returns>资源对象</returns>
	public override T GetAsset<T>()
	{
        if (m_Request != null && m_Request.isDone)
        {
            return m_Request.asset as T;
        }
        else
        {
            return null;
        }
	}
    /// <summary>
    /// 帧更新
    /// </summary>
    /// <returns>true：工作中，false：工作完毕</returns>
	public override bool Update()
	{
        if (m_Request != null)
        {
            return false;
        }

		LoadedAssetBundle bundle = AssetBundleManager.Instance().GetLoadedAssetBundle(m_AssetBundleName, out m_DownloadingError);
		if (bundle != null)
		{
			m_Request = bundle.m_AssetBundle.LoadAssetAsync(m_AssetName, m_Type);
			return false;
		}
		else
		{
			return true;
		}
	}
    /// <summary>
    /// 是否加载完毕
    /// </summary>
    /// <returns></returns>
	public override bool IsDone()
	{
        // 加载过程中出现错误（有可能是在加载自身，也有可能是在加载依赖的资源）
		if (m_Request == null && m_DownloadingError != null)
		{
			Debug.LogError(m_DownloadingError);
			return true;
		}

		return m_Request != null && m_Request.isDone;
	}
}

